package fahrenbacher.server;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.EmbeddedEntity;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.SortDirection;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import fahrenbacher.client.DatabaseService;
import fahrenbacher.server.DatabaseOperations;
public class DatabaseOperations extends RemoteServiceServlet implements DatabaseService {
private DatastoreService database;
private static final DatabaseOperations sharedInstance=new DatabaseOperations();
private DatabaseOperations(){
database = DatastoreServiceFactory.getDatastoreService();
}
//This will return the databaseOperations, which is used to call the database methods
public static DatabaseOperations getSharedInstance(){
return sharedInstance;
}
//this method creates a new school *****Case Sensitive*****
public void newSchool(String schoolName) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Entity en = new Entity(schoolKey);
database.put(en);
}
//this method will create a new account *****Case Sensitive*****
public String newClub(String clubName, String schoolName, String password, String email) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
Entity club = new Entity(clubKey);
try{
Entity c = database.get(clubKey);
return "This Club Already Exists";
}
catch (Exception e) {
club.setProperty("Trees Planted",0);
club.setProperty("Trees Needed", 0);
club.setProperty("Password", password);
club.setProperty("Email", email);
club.setProperty("Carbon", 0);
database.put(club);
return "New Club Created";
}
}
/*public boolean addPlants(String clubName, double carbonOffset) throws EntityNotFoundException{
Entity club=database.get((Key)database.get(this.codexKey).getProperty(clubName));
EmbeddedEntity carbon= new EmbeddedEntity();
carbon.setProperty("Carbon Offset", carbonOffset);
club.setProperty("Trees", carbon);
return true;
}*/
/*public void newTrip(String clubName, int distance) throws EntityNotFoundException{
Entity trip=new Entity("Trip",(Key)database.get(this.codexKey).getProperty(clubName));
trip.setProperty("Total Distance", distance);
database.put(trip);
}*/
//This method gets the actual school given its name *****Case Sensitive***** YOU WILL PROBABLY NEVER USE THIS METHOD
public Entity getSchool(String schoolName) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
return database.get(schoolKey);
}
//This method gets the actual club, given the name and school *****Case Sensitive***** YOU WILL PROBABLY NEVER USE THIS METHOD
public Entity getClub(String schoolName, String clubName) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
return database.get(clubKey);
}
//Checks if school exists
public boolean schoolExists(String schoolName){
Key schoolKey = KeyFactory.createKey("School", schoolName);
try {
database.get(schoolKey);
return true;
} catch (EntityNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
//Checks if club exists
public boolean clubExists(String schoolName, String clubName){
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
try {
database.get(clubKey);
return true;
} catch (EntityNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
//This method gets the password of the user. *****Case Sensitive*****
public String getClubPassword(String schoolName, String clubName) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
return (String) database.get(clubKey).getProperty("Password");
}
//This method will get the club's email address
public String getClubEmail(String schoolName, String clubName) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
return (String) database.get(clubKey).getProperty("Email");
}
//This method will set a new email address for the club
public void setClubEmail(String schoolName, String clubName, String email) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
Entity club = database.get(clubKey);
club.setProperty("Email", email);
database.put(club);
}
//This method sets the password for the user. This can be used when creating a new account or when changing the password. *****Case Sensitive*****
public void setClubPassword(String schoolName, String clubName, String password) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
Entity club =database.get(clubKey);
club.setProperty("Password", password);
database.put(club);
}
//This method deletes the club given the clubname and school name
public void deleteClub(String schoolName, String clubName) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
database.delete(clubKey);
}
//This sets the amount of trees that the club needs to plant, and the amount of trees the club has already planted
public void setTrees(String schoolName, String clubName, int treesPlanted, int treesNeeded) throws EntityNotFoundException{
Entity club = getClub(schoolName, clubName);
club.setProperty("Trees Planted", treesPlanted);
club.setProperty("Trees Needed", treesNeeded);
database.put(club);
}
//Returns the amount of trees that the club has already planted
public int getPlantedTrees(String schoolName, String clubName) throws EntityNotFoundException{
int trees;
Entity club= getClub(schoolName, clubName);
trees = (Integer) club.getProperty("Trees Planted");
return trees;
}
//Returns the amount of trees that the club needs to plant
public int getNeededTrees(String schoolName, String clubName) throws EntityNotFoundException{
int trees;
Entity club= getClub(schoolName, clubName);
trees = (Integer) club.getProperty("Trees Needed");
return trees;
}
//Adds a new Trip
public void addNewTrip(String schoolName, String clubName, String tripName){
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
Key tripKey= KeyFactory.createKey(clubKey, "Trip", tripName);
Entity trip = new Entity(tripKey);
trip.setProperty("Trip Name", tripName);
trip.setProperty("Carbon", 0);
database.put(trip);
}
//Adds Bus Route, Distance is in Miles, Takes Distance both to and from destination on Local roads and Highway, and sets the date. Put (....,0,0,0) for trips with no specified date
public void addBusRoute(String schoolName, String clubName,String tripName, String routeName, int highwayDistance, int localDistance, int highwayReturn, int localReturn, int year, int month, int day){
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
Key tripKey= KeyFactory.createKey(clubKey, "Trip", tripName);
Key routeKey = KeyFactory.createKey(tripKey, "Route", routeName);
Entity route =new Entity(routeKey);
route.setProperty("Highway Distance", highwayDistance);
route.setProperty("Highway Return", highwayReturn);
route.setProperty("Local Distance", localDistance);
route.setProperty("Local Return", localReturn);
route.setProperty("Year", year);
route.setProperty("Month", month);
route.setProperty("Day", day);
route.setProperty("Route Name", routeName);
database.put(route);
}
//Adds Car Route, Distance is in Miles, Takes Distance both to and from destination on Local roads and Highway, and sets the date. Put (....,0,0,0) for trips with no specified date
public void addCarRoute(String schoolName, String clubName,String tripName, String routeName, int highwayDistance, int localDistance, int highwayReturn, int localReturn, int year, int month, int day){
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
Key tripKey= KeyFactory.createKey(clubKey, "Trip", tripName);
Key routeKey = KeyFactory.createKey(tripKey, "Route", routeName);
Entity route =new Entity(routeKey);
route.setProperty("Highway Distance", highwayDistance);
route.setProperty("Highway Return", highwayReturn);
route.setProperty("Local Distance", localDistance);
route.setProperty("Local Return", localReturn);
route.setProperty("Year", year);
route.setProperty("Month", month);
route.setProperty("Day", day);
route.setProperty("Route Name", routeName);
database.put(route);
}
//Adds Plane Route, Distance is in Miles, and sets the date. Put (....,0,0,0) for trips with no specified date
public void addPlaneRoute(String schoolName, String clubName,String tripName, String routeName, int distance, int returnDistance, int year, int month, int day){
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
Key tripKey= KeyFactory.createKey(clubKey, "Trip", tripName);
Key routeKey = KeyFactory.createKey(tripKey, "Route", routeName);
Entity route = new Entity(routeKey);
route.setProperty("Flight Distance", distance);
route.setProperty("Return Flight", returnDistance);
route.setProperty("Year", year);
route.setProperty("Month", month);
route.setProperty("Day", day);
route.setProperty("Route Name", routeName);
database.put(route);
}
//Returns a Trip, in the form of an Entity
public Entity getTrip(String schoolName, String clubName,String tripName) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
Key tripKey= KeyFactory.createKey(clubKey, "Trip", tripName);
return database.get(tripKey);
}
//Returns the route from the trip
public Entity getRoute(String schoolName, String clubName, String tripName, String routeName) throws EntityNotFoundException{
Key schoolKey = KeyFactory.createKey("School", schoolName);
Key clubKey = KeyFactory.createKey(schoolKey, "Club", clubName);
Key tripKey= KeyFactory.createKey(clubKey, "Trip", tripName);
Key routeKey= KeyFactory.createKey(tripKey, "Route", routeName);
return database.get(routeKey);
}
//Change Trip, Distance is in Miles
public void modifyTrip(Entity trip, int newDistance){
trip.setProperty("Distance", newDistance);
database.put(trip);
}
//This method allows the user to edit the date that the trip occurred
public void modifyTripDate(Entity trip, int year, int month, int day){
trip.setProperty("Year", year);
trip.setProperty("Month", month);
trip.setProperty("Day", day);
database.put(trip);
}
//set route carbon
public void setRouteCarbon(String schoolName, String clubName, String tripName, String routeName, double carbon) throws EntityNotFoundException{
Entity route = getRoute(schoolName, clubName, tripName, routeName);
route.setProperty("Carbon", carbon);
}
//gets the routes carbon
public double getRouteCarbon(String schoolName, String clubName, String tripName, String routeName) throws EntityNotFoundException{
Entity route = getRoute(schoolName, clubName, tripName, routeName);
return (Double) route.getProperty("Carbon");
}
//gets the carbon of one trip
public double getTripsCarbon(String schoolName, String clubName, String tripName) throws EntityNotFoundException{
Entity trip = getTrip(schoolName, clubName, tripName);
return (Double) trip.getProperty("Carbon");
}
//gets the carbon of one club
public double getCarbon(String schoolName, String clubName) throws EntityNotFoundException{
Entity club = getClub(schoolName, clubName);
return (Double) club.getProperty("Carbon");
}
//Returns and ArrayList of Strings with each entry being a single string with format "TripName#CarbonValue@Day/Month/Year"
public ArrayList<String> getClubTripsCarbon(String schoolName, String clubName, int year1, int month1, int year2, int month2) throws EntityNotFoundException{
ArrayList<String> trips= new ArrayList<String>();
List<Entity> preliminaryTrips =getTripsByDate(schoolName, clubName, year1, month1, year2, month2);
for(Entity e:preliminaryTrips){
String s = "";
s+=e.getProperty("Trip Name")+"#"+e.getProperty("Carbon")+"@"+e.getProperty("Day")+"/"+e.getProperty("Month")+"/"+e.getProperty("Year");
}
return trips;
}
//gets the Carbon
public List<Entity> getTripsByDate(String schoolName, String clubName, int year1, int month1, int year2, int month2) throws EntityNotFoundException{
Entity club = getClub(schoolName, clubName);
Query tripQuery = new Query("Trip", club.getKey());
List<Entity> finalTrips=new ArrayList<Entity>();
tripQuery.addFilter("Year", FilterOperator.LESS_THAN_OR_EQUAL, year2);
tripQuery.addFilter("Year", FilterOperator.GREATER_THAN_OR_EQUAL, year1);
tripQuery.addSort("Year", SortDirection.ASCENDING)
.addSort("Month", SortDirection.ASCENDING);
List<Entity> trips = database.prepare(tripQuery).asList(FetchOptions.Builder.withDefaults());
for(Entity e: trips){
if((Integer)e.getProperty("Year")==year1){
if((Integer)e.getProperty("Month")>=month1){
finalTrips.add(e);
}
}
else if((Integer)e.getProperty("Year")==year2){
if((Integer)e.getProperty("Month")<=month2){
finalTrips.add(e);
}
}
else{
finalTrips.add(e);
}
}
return finalTrips;
}
//Returns all of the trips from the specified club
public List<Entity> getTrips(String schoolName, String clubName) throws EntityNotFoundException{
Entity club = getClub(schoolName, clubName);
Query tripQuery = new Query("Trip", club.getKey());
List<Entity> finalTrips=new ArrayList<Entity>();
tripQuery.addSort("Year", SortDirection.ASCENDING)
.addSort("Month", SortDirection.ASCENDING);
finalTrips = database.prepare(tripQuery).asList(FetchOptions.Builder.withDefaults());
return finalTrips;
}
//Gets all of the routes for the specified trip
public List<Entity> getRoutes(String schoolName, String clubName, String tripName) throws EntityNotFoundException{
Entity trip = getTrip(schoolName, clubName, tripName);
Query tripQuery = new Query("Route", trip.getKey());
List<Entity> finalTrips=new ArrayList<Entity>();
finalTrips = database.prepare(tripQuery).asList(FetchOptions.Builder.withDefaults());
return finalTrips;
}
//Balances the carbon for the club from the routes up, totaling up the correct carbon values of each entity
public void balance(String schoolName, String clubName, String tripName) throws EntityNotFoundException{
Entity club = getClub(schoolName, clubName);
List<Entity> trips =getTrips(schoolName, clubName);
int clubCarbon=0;
for(int i=0; i<trips.size(); i++){
int carbon=0;
List<Entity> routes = getRoutes(schoolName, clubName, (String)trips.get(i).getProperty("Trip Name"));
for(int k=0; k<routes.size(); k++){
carbon+=(Integer)routes.get(k).getProperty("Carbon");
}
trips.get(i).setProperty("Carbon", carbon);
clubCarbon+=carbon;
}
club.setProperty("Carbon", clubCarbon);
}
//Gets the carbon for all of the clubs in the school
public double getSchoolCarbon(String schoolName) throws EntityNotFoundException{
Entity school=getSchool(schoolName);
double carbon=0;
Query q = new Query("Club", school.getKey());
List <Entity> clubs=database.prepare(q).asList(FetchOptions.Builder.withDefaults());
for(Entity e:clubs){
carbon+=(Double)getCarbon(schoolName, (String)e.getProperty("Trip Name"));
}
return carbon;
}
}